package org.lql.algo.codecrush.week004;

/**
 * @author: liangqinglong
 * @date: 2025-08-01 17:44
 * @description: 面试题 03.01. 三合一 <a href="https://leetcode.cn/problems/three-in-one-lcci/description/">...</a>
 **/
public class TripleInOne {


	/**
	 * 三合一。描述如何只用一个数组来实现三个栈。
	 * <p>
	 * 你应该实现push(stackNum, value)、pop(stackNum)、isEmpty(stackNum)、peek(stackNum)方法。stackNum表示栈下标，value表示压入的值。
	 * <p>
	 * 构造函数会传入一个stackSize参数，代表每个栈的大小。
	 * <p>
	 * 示例 1：
	 * <p>
	 * 输入：
	 * ["TripleInOne", "push", "push", "pop", "pop", "pop", "isEmpty"]
	 * [[1], [0, 1], [0, 2], [0], [0], [0], [0]]
	 * 输出：
	 * [null, null, null, 1, -1, -1, true]
	 * 说明：当栈为空时`pop, peek`返回-1，当栈满时`push`不压入元素。
	 * 示例 2：
	 * <p>
	 * 输入：
	 * ["TripleInOne", "push", "push", "push", "pop", "pop", "pop", "peek"]
	 * [[2], [0, 1], [0, 2], [0, 3], [0], [0], [0], [0]]
	 * 输出：
	 * [null, null, null, null, 2, 1, -1, -1]
	 * <p>
	 * <p>
	 * 提示：
	 * <p>
	 * 0 <= stackNum <= 2
	 */

	private int[] arr;        // 存储所有栈的数据
	private int stackSize;    // 每个栈的大小
	private int[] tops;       // 每个栈当前的元素个数（top指针）

	public TripleInOne(int stackSize) {
		this.stackSize = stackSize;
		this.arr = new int[stackSize * 3]; // 3个栈
		this.tops = new int[3];            // 每个栈的当前长度（初始为0）
	}

	public void push(int stackNum, int value) {
		if (tops[stackNum] >= stackSize) {
			return; // 栈已满
		}
		int index = stackNum * stackSize + tops[stackNum]; // 当前栈的写入位置
		arr[index] = value;
		tops[stackNum]++;
	}

	public int pop(int stackNum) {
		if (tops[stackNum] == 0) {
			return -1; // 栈为空
		}
		tops[stackNum]--;
		int index = stackNum * stackSize + tops[stackNum];
		return arr[index];
	}

	public int peek(int stackNum) {
		if (tops[stackNum] == 0) {
			return -1; // 栈为空
		}
		int index = stackNum * stackSize + tops[stackNum] - 1;
		return arr[index];
	}

	public boolean isEmpty(int stackNum) {
		return tops[stackNum] == 0;
	}

	public static void main(String[] args) {
		TripleInOne tripleInOne = new TripleInOne(1);
		tripleInOne.push(0, 1);
		tripleInOne.push(0, 2);
		System.out.println(tripleInOne.pop(0));
		System.out.println(tripleInOne.pop(0));
		System.out.println(tripleInOne.pop(0));
		System.out.println(tripleInOne.isEmpty(0));
	}
}
